package com.ebupt.migu.music.hangupsms.service.impl;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ebupt.migu.common.util.RestHttpUtil;
import com.ebupt.migu.music.common.entity.ResultObject;
import com.ebupt.migu.music.common.util.RedisUtil;
import com.ebupt.migu.music.hangupsms.config.HangUpSmsConfig;
import com.ebupt.migu.music.hangupsms.entity.*;
import com.ebupt.migu.music.hangupsms.mapper.IssueInfoMapper;
import com.ebupt.migu.music.hangupsms.service.IIssueInfoService;
import com.ebupt.migu.music.hangupsms.utils.DidUtils;
import com.ebupt.migu.music.hangupsms.utils.LocalDateTimeUtils;
import com.ebupt.migu.music.hangupsms.utils.ThreadContext;
import com.ebupt.migu.music.market.entity.MarketSmsCount;
import com.ebupt.migu.music.market.entity.MarketSmsStrategy;
import com.ebupt.migu.music.market.service.MarketSmsCountService;
import com.ebupt.migu.music.roster.entity.RosterBlackEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.omg.CORBA.SystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Service
public class IssueInfoServiceImpl extends ServiceImpl<IssueInfoMapper, IssueInfo> implements IIssueInfoService {

    @Value("${hangup.phoneUrl}")
    private String phoneUrl;
    @Value("${hangup.smsUrl}")
    private String smsUrl;
    @Value("${hangup.ringUrl}")
    private String ringUrl;
    @Value("${hangup.did}")
    private String did;
    @Value("${hangup.pwd}")
    private String pwd;
    @Value("${hangup.platform}")
    private String platform;
    @Autowired
    private HangUpSmsConfig hangUpSmsConfig;
    @Autowired
    private IssueInfoMapper issueInfoMapper;
    @Resource
    private RedisUtil redisClient;
    public static final String          YYYY_MM                          = "yyyyMM";
    public static final String          YYYY_M_MDD                       = "yyyyMMdd";
    public static final String          DEFAULT                          = "default";
    public static final String          MSGCOUNT                         = "MSGCOUNT_";
    public static final String          COUNTLIMIT                       = "COUNTLIMIT";
    public static final String          ACCESS_PLATFORM_ID               = "014000E";
    public static final String          SECOND_FORMAT                    = "yyyyMMddHHmmss";
    /**
     * 权益类型
     */
    public static final String          RIGHTS_FIELD_CONTENT_TYPE        = "contentType";
    /**
     * redis加锁value值
     */
    public static final String          REDIS_LOCK_VALUE                 = "1";
    /**
     * 话单中，手机号位置
     */
    private static final int            CALL_BILL_CALLER_PHONE_INDEX     = 0;
    /**
     * 话单中，手机号位置
     */
    private static final int            CALL_BILL_PHONE_INDEX            = 1;
    /**
     * 话单中，铃音ID位置
     */
    private static final int            CALL_BILL_TONE_ID_INDEX          = 3;
    /**
     * 话单中，结束时间位置
     */
    private static final int            CALL_BILL_END_TIME_INDEX         = 5;
    /**
     * 铃音类型
     */
    private static final int            CALL_BILL_TYPE_INDEX             = 11;
    /**
     * 铃音类型
     */
    private static final int            CALL_BILL_TYPE_INDEX_NEW         = 10;
    private static final String         CALL_BILL_LIST_KAFKA_SWITCH_OPEN = "1";
    /**
     * 用户类型： 0 手机号
     */
    private static final String         USER_TYPE_MSISDN                 = "0";
    @Autowired
    private MarketSmsCountService countService;
    public String isMobile(String phoneNo) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("phoneNo", phoneNo);
        // 调用HTTP接口
        try {
            String	result = RestHttpUtil.doGet(phoneUrl+"/phoneCode/getProvinceId", paramsMap);
            log.info("调用移动手机号查询接口:{},返回结果:{}",phoneNo, result);
            if (result != null) {
                JSONObject jsonObject1 = JSONObject.parseObject(result);
                String resultCode = (String) jsonObject1.get("resultCode");
                String resultMessage = (String) jsonObject1.get("resultMessage");
                if (!"000000".equals(resultCode)) {
                    throw new Exception("调用移动手机号查询接口异常:" + resultMessage + ",phoneNo--》" + phoneNo);
                }
                Object o = jsonObject1.get("data");
                if(null!=o){
                    String o1 = (String)o;
                    return o1;
                }
               return null;
            }
            return null;
        } catch (Exception e) {
            log.error("调用移动手机号查询接口失败,phoneNo-->{}", phoneNo);
            return null;
        }
    }

    public boolean getCrbtStatus(BillInfo info) throws Exception {
        VrbtSendMsg send = info.getEvent();
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("did", send.getDid());
        paramsMap.put("didpwd", send.getDidpwd());
        paramsMap.put("seq", send.getSeq());
        paramsMap.put("accessPlatformID", send.getAccessPlatformID());
        paramsMap.put("role", "000");
        paramsMap.put("roleCode", "000");
        paramsMap.put("msisdn", info.getCallerPhone());
        // 调用HTTP接口
        try {
            String	result = RestHttpUtil.doPost(ringUrl+"/egateway-crbt/peforbusms/music/query-crt-status/v1.0", paramsMap);
            log.info("调用音频彩铃功能状态接口:{},返回结果:{}",info.getCallerPhone(), result);
            if (result != null) {
                JSONObject jsonObject1 = JSONObject.parseObject(result);
                String resultCode = (String)jsonObject1.get("code");
                String resultMessage = (String)jsonObject1.get("info");
                if(!"000000".equals(resultCode)){
                    throw new Exception("调用音频彩铃功能状态接口异常:"+resultMessage+",mobile--》"+info.getCallerPhone());
                }
                String crtStatus = (String)jsonObject1.get("crtStatus");
                if("1".equals(crtStatus)){
                    return true;
                }
                return false;
            }
            return false;
        } catch (Exception e) {
            log.error("调用音频彩铃功能状态接口失败,mobile-->{}", send.getMsisdn());
            throw new Exception(e);
        }
    }

    public String getVrbtStatus(BillInfo billInfo) throws Exception {
        VrbtSendMsg send = billInfo.getEvent();
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("did", send.getDid());
        paramsMap.put("didpwd", send.getDidpwd());
        paramsMap.put("seq", send.getSeq());
        paramsMap.put("accessPlatformID", send.getAccessPlatformID());
        paramsMap.put("role", "000");
        paramsMap.put("roleCode", "000");
        paramsMap.put("msisdn", billInfo.getCallerPhone());
        paramsMap.put("productType", "0");
        // 调用HTTP接口
        try {
            String	result = RestHttpUtil.doPost(ringUrl+"/egateway/peforbusms/music/vrbt/usermanage/query-vrbt-status/v3.0", paramsMap);
            log.info("调用视频彩铃功能状态接口:{},返回结果:{}",billInfo.getCallerPhone(), result);
            if (result != null) {
                JSONObject jsonObject1 = JSONObject.parseObject(result);
                String resultCode = (String)jsonObject1.get("code");
                String resultMessage = (String)jsonObject1.get("info");
                if(!"000000".equals(resultCode)){
                    throw new Exception("调用视频彩铃功能状态接口异常:"+resultMessage+",mobile--》"+send.getMsisdn());
                }
                String vrbtstatus = (String)jsonObject1.get("vrbtstatus");
                return vrbtstatus;
            }
            return "0";
        } catch (Exception e) {
            log.error("调用视频彩铃功能状态接口失败,mobile-->{}", billInfo.getCallerPhone());
            throw new Exception(e);
        }
    }

    public String getBaseVipStatus(BillInfo billInfo) throws Exception {
        VrbtSendMsg send = billInfo.getEvent();
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("did", send.getDid());
        paramsMap.put("didpwd", send.getDidpwd());
        paramsMap.put("seq", send.getSeq());
        paramsMap.put("accessPlatformID", send.getAccessPlatformID());
        paramsMap.put("userAccount", billInfo.getCallerPhone());
        paramsMap.put("userAccountType", "0");
        Map map = new HashMap();
        List arrayList= new ArrayList<>();
        map.put("rightsField", "contentType");
        map.put("rightsValue", "131");
        arrayList.add(map);
        paramsMap.put("rightsList",arrayList);

    // 调用HTTP接口
        try {
            String	result = RestHttpUtil.doPost(ringUrl+"/egateway-music/peforbusms/miguNet/queryContractRights.action",paramsMap);
            log.info("调用基础会员查询接口:{},返回结果:{}",paramsMap, result);
            if (result != null) {
                JSONObject jsonObject1 = JSONObject.parseObject(result);
                JSONObject o =(JSONObject) jsonObject1.get("result");
                String resultCode = (String)o.get("resultCode");
                String resultMessage = (String)o.get("resultMessage");
                if(!"000000".equals(resultCode)){
                    throw new Exception("调用基础会员接口异常:"+resultMessage+",mobile--》"+billInfo.getCallerPhone());
                }
                Integer isHasRights = (Integer) jsonObject1.get("isHasRights");
                return isHasRights==1 ? "1" : "0";
            }
            return "0";
        } catch (Exception e) {
            log.error("调用基础会员查询接口失败,mobile-->{}", billInfo.getCallerPhone());
            throw new Exception(e);
        }
    }

    @Override
    public List<MarketSmsStrategy> queryStrategy(BillInfo billInfo) {
        Date dateStart = DateUtil.parse(billInfo.getStartTime(), "yyyyMMddHHmmss");
        Date dateEnd = DateUtil.parse(billInfo.getEndTime(), "yyyyMMddHHmmss");
        // 计算两个日期之间相差的秒数
        long diffSeconds = DateUtil.between(dateStart, dateEnd, DateUnit.SECOND);
        // 主叫|被叫|plus铃音编号|铃音id|开始时间|结束时间
        // 13801396200|13911912008||600926000001209039|20201217092552|20201217092600
        // 新增省份字段：beijing|13801396200|13911912008||600926000001209039|20201217092552|20201217092600
        String userTypeSuffix = getUserTypeSuffix(billInfo);//获取用户类型
        String userType = StringUtils.replace(userTypeSuffix, "_", "");
        billInfo.setDuration(diffSeconds);		// 主叫|被叫|plus铃音编号|铃音id|开始时间|结束时间
        // 13801396200|13911912008||600926000001209039|20201217092552|20201217092600
        // 新增省份字段：beijing|13801396200|13911912008||600926000001209039|20201217092552|20201217092600
        billInfo.setUserType(userType);
        List<MarketSmsStrategy> strategyList = issueInfoMapper.queryStrategy(billInfo);
        return strategyList;
    }

    private String getUserTypeSuffix(BillInfo billInfo) {
        try {
            String vrbtStatus = getVrbtStatus(billInfo);
            if (StringUtils.equals("0", vrbtStatus)) {
                return "0_0";
            }
            String baseVipStatus = getBaseVipStatus(billInfo);
            return vrbtStatus + "_" + baseVipStatus;
        } catch (Exception e) {
            log.error("获取用户类型失败", e);
            return "0_0";
        }
    }

    @Override
    public boolean contentPreProcess(BillInfo billInfo){
        try {
            if(checkSendNum(billInfo)){
                 return false;
            }
            if (checkToneContent(billInfo)) {//校验tongtype是否为1
                return false;
            }
            String calleredProvinceId = getProvinceId(billInfo.getCalleredPhone(), billInfo.getProvinceName());

            if (checkProvince(billInfo.getCallerPhone(), calleredProvinceId, billInfo.getProvinceName())) {//4
                return false;
            }
            // 校验短信发送时间是否超过发送时间
            if (checkStartTime(billInfo.getEndTime(), calleredProvinceId, billInfo.getProvinceName())) {//5
                return false;
            }
            if (checkBlackList(billInfo)){//校验是否在黑名单中
                return false;
            }
            // 铃音id过滤是否需要发送短信
            if (checkContent(billInfo.getToneId(), billInfo.getProvinceName())) {//7
                return false;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
        return true;
    }
    public void contentProcess(BillInfo billInfo){
        String calleredProvinceId = null;
        try {
            // 企业视频彩铃用户不发送短信
             calleredProvinceId = getProvinceId(billInfo.getCalleredPhone(), billInfo.getProvinceName());
            if (checkCorpStatus(billInfo, calleredProvinceId)) {
                return;
            }
        } catch (Exception businessException) {
            return;
        }
        MaxNumInfo maxNumInfo = hangUpSmsConfig.getMaxNumInfoMap().get(billInfo.getCallerProvinceId());
        boolean limitSend = checkUserSendTime(billInfo.getCallerPhone(), maxNumInfo, billInfo.getCallerProvinceId());

        if (limitSend) {
            return;
        }
        TimeLimit timeLimit = getTimeLimit(calleredProvinceId);
        ThreadContext.put(ThreadContext.TIME_LIMIT, timeLimit);
        ThreadContext.put(ThreadContext.HANG_UP_TIME, billInfo.getEndTime());
        boolean expire = redisClient.set(billInfo.getCallerPhone(), REDIS_LOCK_VALUE, hangUpSmsConfig.getCheckPhoneNumInterval());
        if (!expire) {
            log.info("5分钟内不能重复发送");
            return;
        }
        if(checkSendNum(billInfo)){
            redisClient.del(billInfo.getCallerPhone());
            return;
        }
        try {
            ResultObject resultObject = sendMsg(billInfo, calleredProvinceId);
            if (StringUtils.equals("000000", resultObject.getCode())) {
                updateDb(billInfo.getCallerPhone(), billInfo, calleredProvinceId);
            }else{
                redisClient.del(billInfo.getCallerPhone());
            }
        }catch (Exception e) {
            redisClient.del(billInfo.getCallerPhone());
            log.error("短信发送失败", e);
        }
    }
    private void updateDb(String calledPhone, BillInfo billInfo, String provinceId) {
        IssueInfo info = new IssueInfo();
        info.setPhoneNumber(calledPhone);
        info.setDeliverPort(billInfo.getSmsStrategy().getSendPort());
        info.setStrategyId(billInfo.getSmsStrategy().getStrategyId());
        info.setDeliverTime(new Date());
        info.setLocalId(Integer.valueOf(hangUpSmsConfig.getProvinceAndLocalIdMap().get(provinceId)));
        this.save(info);
    }
    private String getProvinceId(String calledPhone, String provinceName) {
        String callerProvinceId = "";
        callerProvinceId = hangUpSmsConfig.getProvinceNameAndIdMap().get(provinceName);
        return callerProvinceId;
    }
    public boolean checkToneContent(BillInfo billInfo){
        String toneType = billInfo.getToneType();
        if (StringUtils.isNotEmpty(toneType) && !toneType.equals("1")) {//3
//            redisCount(billInfo.getProvinceName(), "INDEX_12");
                log.info( "播放被叫铃音之外的铃音内容不发送短信");

            return true;
        }
        return false;
    }
    public boolean checkSendNum(BillInfo billInfo){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("strategy_id", billInfo.getSmsStrategy().getStrategyId());
        MarketSmsCount one = countService.getOne(queryWrapper);
        if(null==one){
            return false;
        }
        if (one.getCount()>=billInfo.getSmsStrategy().getSendNum()) {//3
            log.info( "超过策略下发短信数量,{}",billInfo.getSmsStrategy().getStrategyId());
            return true;
        }
        return false;
    }

    public BillInfo getBillInfo(String content) {
        BillInfo billInfo = new BillInfo();
        String[] params = content.split("\\|");
        if (params.length < 5) {
            billInfo.setCanSend(false);
            return billInfo;
        }
        if (StringUtils.isNumeric(params[0])) {
            billInfo.setCallerPhone(params[CALL_BILL_CALLER_PHONE_INDEX]);
            billInfo.setCalleredPhone(params[CALL_BILL_PHONE_INDEX]);
            billInfo.setToneId(params[CALL_BILL_TONE_ID_INDEX]);
            billInfo.setEndTime(params[CALL_BILL_END_TIME_INDEX]);
        } else {
            billInfo.setProvinceName(params[0]);
            // beijing|13801396200|13911912008||600926000001209039|20201217092552|20201217092600
            if (params.length < 6) {
                billInfo.setCanSend(false);
                return billInfo;
            }
            billInfo.setCallerPhone(params[CALL_BILL_CALLER_PHONE_INDEX + 1]);
            billInfo.setCalleredPhone(params[CALL_BILL_PHONE_INDEX + 1]);
            billInfo.setToneId(params[CALL_BILL_TONE_ID_INDEX + 1]);
            billInfo.setEndTime(params[CALL_BILL_END_TIME_INDEX + 1]);
            billInfo.setStartTime(params[CALL_BILL_END_TIME_INDEX]);
            if (params.length >= 12) {
                billInfo.setToneType(params[CALL_BILL_TYPE_INDEX]);
            }
        }
        VrbtSendMsg event = new VrbtSendMsg();
        event.setDid(did);
        event.setSeq(DidUtils.generateSeq(did));
        event.setDidpwd(DidUtils.generateMD5String(event.getSeq() + pwd));
        event.setAccessPlatformID(platform);
        billInfo.setEvent(event);
        return billInfo;
    }

    private boolean canLimit(String provinceId) {
        int limitNum = Integer.parseInt(hangUpSmsConfig.getLimitCountMap().get(provinceId)); // 获取注解每秒加入桶中的token
        LocalDateTime now = LocalDateTime.now();
        String redisKey = "RATELIMITER_" + now.format(DateTimeFormatter.ofPattern(SECOND_FORMAT)) + "_" + provinceId;
        // 当多个节点操作同一个key的时候，先增加计数。避免下面的情况发生
        // 假设有A、B、C节点，如果我们限流50，而当前redis计数是49.
        // A、B、C三个节点如果同时取出数据（49），三个节点判断（49 < 50），那么实际达到的QPS会是52
        long currentCount = redisClient.incr(redisKey,1);
        if (currentCount == 1) { // 只有一个节点会满足该条件
            redisClient.expire(redisKey, hangUpSmsConfig.getCheckPhoneNumInterval());
        }

        try {
            if (currentCount <= limitNum) {
                // 执行方法
                if (hangUpSmsConfig.isNeedLog()) {
                    log.info("放行流量,当前时间%s,%s", now.format(DateTimeFormatter.ofPattern(SECOND_FORMAT)), provinceId);
                }
                return false;
            } else {
                // 拒绝了请求（服务降级）
                //redisCount(userSendMsgInfo.getProvinceName(), "CURRENTLIMIT");
                if (hangUpSmsConfig.isNeedLog()) {
                    log.info("限流了,当前时间%s,%s", now.format(DateTimeFormatter.ofPattern(SECOND_FORMAT)), provinceId);
                }
                return true;
            }
        } catch (Exception throwable) {
            log.info("限流器异常,{}",throwable.getMessage());
        }
        return false;
    }
    private boolean checkBlackList(BillInfo info){
        String blackId = info.getSmsStrategy().getBlackList();
        if(StringUtils.isEmpty(blackId)){
           return false;
        }
        RosterBlackEntity rosterBlackEntity = issueInfoMapper.queryRosterBlackEntity(blackId);
        if(info.getCallerPhone().matches(rosterBlackEntity.getMsisdn())){
            log.info("黑名单用户,{}",info.getCallerPhone());
            return true;
        }
        return false;
    }
    private boolean checkStartTime(String endTime, String provinceId, String provinceName) throws ParseException {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern(SECOND_FORMAT));

        TimeLimit timeLimit = getTimeLimit(provinceId);
        if (now.isAfter(end.plusMinutes(timeLimit.getLimitNum()))) {
           // redisCount(provinceName, "OUTTIME");
            if (hangUpSmsConfig.isNeedLog()) {
                log.info( "超过话单超时时间，不再处理");
            }
            return true;
        }
        // 当前时间是否在该省可以发送短信的时间内
        try {
            // 当前时间是否在该省可以发送短信的时间内
           // Date nowTime = DateUtil.parse(DateUtil.formatTime(new Date()), "yyyyMMddHHmmss");
            DateTime nowTime = DateUtil.parse(new SimpleDateFormat("HH:mm:ss").format(new Date()), "HH:mm:ss");
            if (!timeCalendar(nowTime, DateUtil.parse(timeLimit.getStartTimeOfDay(), "HH:mm:ss"),
                    DateUtil.parse(timeLimit.getEndTimeOfDay(), "HH:mm:ss"))) {
                if (hangUpSmsConfig.isNeedLog()) {
                    log.info( "不在省份允许发送短信的时间范围内，不再处理");
                }
                return true;
            }
        } catch (SystemException e) {
            log.info("时间转换失败");
            return true;
        }
        return false;
    }
    public static boolean timeCalendar(Date nowTime, Date dayTimeStart, Date dayTimeEnd) {
        // 设置当前时间
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        // 设置开始时间
        Calendar timeStart = Calendar.getInstance();
        timeStart.setTime(dayTimeStart);
        // 设置结束时间
        Calendar timeEnd = Calendar.getInstance();
        timeEnd.setTime(dayTimeEnd);
        return date.after(timeStart) && date.before(timeEnd);
    }
    public void redisCount(String provinceName, String keyName) {
        try {
            if (hangUpSmsConfig.isNeedCountLog()) {
                LocalDateTime now = LocalDateTime.now();
                Long dayCount = redisClient.incr(MSGCOUNT + provinceName + "_" + keyName + "_" + now.format(DateTimeFormatter.ofPattern(YYYY_M_MDD)),1);
                if (dayCount == 1) {
                    redisClient.expire(
                            MSGCOUNT +
                                    provinceName +
                                    "_" +
                                    keyName +
                                    "_" +
                                    now.format(DateTimeFormatter.ofPattern(YYYY_M_MDD)),
                            60 * 60 * 24 * 40);
                }
            }
        } catch (Exception e) {
            log.info("redis计数失败,provinceName:{},keyName:{}", provinceName, keyName);
        }
    }

    private TimeLimit getTimeLimit(String provinceId) {
        Map<String, TimeLimit> provinceTimeLimitMap = hangUpSmsConfig.getProvinceTimeLimitMap();
        TimeLimit provincetimeLimit = provinceTimeLimitMap.get(provinceId);
        TimeLimit defaultTimeLimit = provinceTimeLimitMap.get(DEFAULT);
        if (provincetimeLimit == null) {
            return defaultTimeLimit;
        }

        provincetimeLimit.setStartTimeOfDay(StringUtils.defaultIfEmpty(provincetimeLimit.getStartTimeOfDay(), defaultTimeLimit.getStartTimeOfDay()));
        provincetimeLimit.setEndTimeOfDay(StringUtils.defaultIfEmpty(provincetimeLimit.getEndTimeOfDay(), defaultTimeLimit.getEndTimeOfDay()));
        provincetimeLimit.setLimitNum(provincetimeLimit.getLimitNum() != 0 ? provincetimeLimit.getLimitNum() : defaultTimeLimit.getLimitNum());
        return provincetimeLimit;
    }

    private boolean checkContent(String toneId, String provinceName) {//过滤铃音id
        // G位为14569不发
        if (toneId.substring(6, 7).matches(hangUpSmsConfig.getCallerNoSendGIndex())) {
            redisCount(provinceName, "INDEXG");
            if (hangUpSmsConfig.isNeedLog()) {
                log.info("广告视频彩铃内容或者企业视频彩铃内容不下发短信,toneId:{}", toneId);
            }
            return true;
        }
        if (StringUtils.isNotEmpty(hangUpSmsConfig.getPrefixsToneid())) {
            String[] split = hangUpSmsConfig.getPrefixsToneid().split("\\|");
            for (int i = 0; i < split.length; i++) {
                if (toneId.startsWith(split[i])) {
                    if (hangUpSmsConfig.isNeedLog()) {
                        log.info( "优先音频铃音不下发短信,toneId:{}", toneId);
                    }
                    return true;
                }
            }
        }
        return false;
    }
//开始处理
    private boolean checkCorpStatus(BillInfo billInfo, String calleredProvinceId) throws Exception {
        // 非移动号码不发送短信
        String callerPhone = billInfo.getCallerPhone();
        if (StringUtils.length(callerPhone) < 11) {
            return true;
        }
        // 查询是否是移动号段
        String phoneCodeWithoutNp = isMobile(billInfo.getCallerPhone());//用主叫号码查
        if (null == phoneCodeWithoutNp || !StringUtils.equals(phoneCodeWithoutNp, calleredProvinceId)) {
           // redisCount(billInfo.getProvinceName(), "NOMOBILE");
            if (hangUpSmsConfig.isNeedLog()) {
                log.info( "非移动号段或不是同个省份不发送短信：{}" + callerPhone);
            }
            return true;
        }
        billInfo.setCallerProvinceId(phoneCodeWithoutNp);
        if (phoneCodeWithoutNp.matches(hangUpSmsConfig.getNeedCheckCorpProvinceIds())) {
            // 这里需要查询主叫用户的localId 这里需要查询是否是音频彩铃用户
            boolean crbtStatus = getCrbtStatus(billInfo);
            if (crbtStatus) {
                //redisCount(billInfo.getProvinceName(), "CRBTUSER");
                if (hangUpSmsConfig.isNeedLog()) {
                    log.info("音频彩铃用户不发短信：{}", callerPhone);
                }
                return true;
            }
        }
        return false;
    }
//    private boolean isLimitSend(LimitSendParam param) {
//
//    }

    private boolean checkUserSendTime(String callerPhone,
                                      MaxNumInfo maxNumInfo,
                                      String provinceId) {//是否超过每日每周每月最大次数
        String localId = hangUpSmsConfig.getProvinceAndLocalIdMap().get(provinceId);
        //List<UserSendMsgInfo> userSendMsgInfos = issueInfoMapper.querySendMsgUserInfo(callerPhone, Integer.valueOf(localId));
        QueryWrapper<IssueInfo> issueInfoQueryWrapper = new QueryWrapper<>();
        issueInfoQueryWrapper.eq("phone_number", callerPhone);
        issueInfoQueryWrapper.eq("local_id", localId);
        List<IssueInfo> userSendMsgInfos = this.list(issueInfoQueryWrapper);
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startDayOfMonth = LocalDateTimeUtils.getStartOrEndDayOfMonth(now.toLocalDate(), true);
        LocalDateTime startDayOfWeek = LocalDateTimeUtils.getStartOrEndDayOfWeek(now.toLocalDate(), true);
        LocalDateTime startDayOfDay = LocalDateTimeUtils.getStartOrEndDayOfDay(now.toLocalDate(), true);
        int currentNumOfDay = 0;
        int currentNumOfWeek = 0;
        int currentNumOfMonth = 0;
        if (checkDayOfMonth(userSendMsgInfos, startDayOfMonth, currentNumOfMonth, maxNumInfo.getMaxMonthNum())) {
            //redisCount(provinceName, COUNTLIMIT);
            return true;
        }
        if (checkDayOfMonth(userSendMsgInfos, startDayOfWeek, currentNumOfWeek, maxNumInfo.getMaxWeekNum())) {
            //redisCount(provinceName, COUNTLIMIT);
            return true;
        }
        if (checkDayOfMonth(userSendMsgInfos, startDayOfDay, currentNumOfDay, maxNumInfo.getMaxDayNum())) {
            //redisCount(provinceName, COUNTLIMIT);
            return true;
        }
        return false;
    }

    private boolean checkDayLimit(String localId,String dayformat,List<UserSendMsgInfo> userSendMsgInfos,
                                  String callerPhone,Integer maxMonthNum) {
        boolean b = redisClient.hasKey(dayformat+"_"+localId+"_"+callerPhone);
        if(b){
            Integer countDay = (Integer)redisClient.get(dayformat + "_" + localId + "_" + callerPhone);
            if (countDay >= maxMonthNum) {
                return true;
            }
        }
        return false;
    }
    private boolean checkDayOfMonth(List<IssueInfo> userSendMsgInfos,
                                    LocalDateTime startDayOfMonth,
                                    int currentNumOfMonth,
                                    Integer maxMonthNum) {
        for (IssueInfo userSendMsgInfo : userSendMsgInfos) {
//            DateTime d = new DateTime();
//            LocalDateTime localDateTime = d.toLocalDateTime();
          //  LocalDateTime sendmsgtime = userSendMsgInfo.getDeliverTime().toLocalDateTime();
            LocalDateTime sendmsgtime = DateUtil.toLocalDateTime(userSendMsgInfo.getDeliverTime());
            if (sendmsgtime.isAfter(startDayOfMonth)) {
                currentNumOfMonth++;
                if (checkLimitNum(currentNumOfMonth, maxMonthNum)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean checkLimitNum(int currentNumOfMonth, Integer maxMonthNum) {
        if (currentNumOfMonth >= maxMonthNum) {
            log.info("发送信息次数超过限制,currentNumOfMonth:{},maxMonthNum:{}", currentNumOfMonth, maxMonthNum);
            return true;
        }
        return false;
    }

    private boolean checkProvince(String calledPhone, String calleredProvinceId, String provinceName) {
        // 这里需要有白名单用户添加
        if (calledPhone.matches(hangUpSmsConfig.getWhiteMsisdns())) {
            return false;
        }
        if (calleredProvinceId.matches(hangUpSmsConfig.getCallerNoSendProvinceIds())) {
//            redisCount(provinceName, "PROVINCE");
            if (hangUpSmsConfig.isNeedLog()) {
                log.info("当前省份不做信息发送,provinceId:{},phone:{}", calleredProvinceId, calledPhone);
            }
            return true;
        }
        return false;
    }
    private Long computeSmsEndTime() {
        TimeLimit timeLimit = ThreadContext.get(ThreadContext.TIME_LIMIT, TimeLimit.class);
        String hangUpTime = ThreadContext.get(ThreadContext.HANG_UP_TIME, String.class);
        Date hangUpDateTime = DateUtil.parse(hangUpTime, SECOND_FORMAT);
        long delayTime = hangUpDateTime.getTime() + timeLimit.getLimitNum() * 60 * 1000L;
        String dateStr = DateUtil.formatDate(new Date());
        String endTimeStr = dateStr + " " + timeLimit.getEndTimeOfDay();
        Date endDateTime = DateUtil.parseDateTime(endTimeStr);
        long endTime = endDateTime.getTime();
        return Math.min(delayTime, endTime) / 1000L;
    }

    public ResultObject sendMsg(BillInfo info, String calleredProvinceId) {
        ResultObject baseRsp = new ResultObject();
        if (canLimit(calleredProvinceId)) {//限流
            baseRsp.setCode("200000");
            log.info("限流不发送,{}",info.getCallerPhone());
            return baseRsp;
        }
        if (calleredProvinceId.matches(hangUpSmsConfig.getNoSendSmsProvinceId())) {
            log.info("短信发送配置生效，手机号：{} 不发送短信", info.getCallerPhone());
            baseRsp.setCode("200000");
            return baseRsp;
        }
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("activityId", info.getSmsStrategy().getStrategyId());
        paramsMap.put("msisdn", info.getCalleredPhone());
        paramsMap.put("sendEndTime",computeSmsEndTime());
        // 调用HTTP接口

            String result = RestHttpUtil.doPost(smsUrl+"/caller-hung-up/send",paramsMap);
            log.info("挂机短信发送接口:{},返回结果:{}",paramsMap, result);
            if (result != null) {
                baseRsp = JSON.parseObject(result, ResultObject.class);
                return baseRsp;
            }
            baseRsp.setCode("10000");
            baseRsp.setMsg("发送失败");
        return baseRsp;
    }


}
